package com.github.facadefs;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 文件操作.
 *
 * @author vacoor
 * @since 1.2.0
 */
public interface Operations {

    /**
     * 给定路径是否存在.
     *
     * @param path 文件系统路径
     * @throws IOException 如果文件系统异常
     */
    boolean exists(final String path) throws IOException;

    /**
     * 获取文件/路径的状态.
     *
     * @param path 文件系统路径
     * @return 返回文件状态, 如果文件不存在返回 null
     * @throws IOException 如果文件系统异常
     */
    FileView stat(final String path) throws IOException;

    /**
     * 获取文件/路径下的文件状态.
     *
     * @param path 文件或目录路径
     * @return 文件或目录的状态, 如果目录下没有文件或文件不存在返回空数组
     * @throws IOException 如果文件系统异常
     */
    FileView[] ls(final String path) throws IOException;

    /**
     * 获取文件/路径下的文件状态.
     *
     * @param path     文件或目录路径
     * @param selector 文件处理器
     * @throws IOException 如果文件系统异常
     * @since 1.2.0
     */
    void ls(final String path, final Selector selector) throws IOException;

    /**
     * 创建给定路径的目录, 如果目录已经创建成功或已经存在返回 true, 创建失败返回 false.
     * 如果已经存在但不是一个目录则抛出异常.
     *
     * @param path 目录路径
     * @throws IOException 如果文件系统异常
     */
    boolean mkdirs(final String path) throws IOException;

    /**
     * 打开给定路径的文件, 如果给定路径不存在返回null, 如果不是文件将抛出异常.
     * <p/>
     * 注: 关闭输入流时才会关闭相关资源, 因此读取完毕后务必关闭输入流.
     *
     * @param path 文件路径
     * @return 文件输入流或null
     * @throws IOException 如果文件系统异常
     */
    InputStream open(final String path) throws IOException;

    /**
     * 获取一个创建文件的输出流并自动创建相关目录, 当 override = false, 如果文件已经存在则抛出异常.
     *
     * @param path     要创建的文件路径
     * @param override 如果文件已经存在是否覆盖
     * @return 新建文件的输出流
     * @throws IOException 如果文件系统异常
     */
    OutputStream create(final String path, final boolean override) throws IOException;

    /**
     * 获取一个创建文件的输出流并自动创建相关目录, 当 override = false, 如果文件已经存在则抛出异常.
     *
     * @param path        要创建的文件路径
     * @param contentType MIME 类型, 某些文件系统会记录该值, 例如 OSS 在返回时使用
     * @param override    如果文件已经存在是否覆盖
     * @return 新建文件的输出流
     * @throws IOException 如果文件系统异常
     */
    OutputStream create(final String path, final String contentType, final boolean override) throws IOException;

    /**
     * 删除给定路径.
     *
     * @param path      文件或目录路径
     * @param recursive 如果文件夹中存在目录是否递归删除
     * @throws IOException 如果文件系统异常
     */
    void rm(final String path, final boolean recursive) throws IOException;

    /**
     * 重命名路径.
     *
     * @param oldPath 源路径
     * @param newPath 目标路径
     * @throws IOException 如果文件系统异常
     */
    void rename(final String oldPath, final String newPath) throws IOException;

}
